#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>
#include <errno.h>
#include "config.h"


//去除字符串中空字符
void trim(char *str) {
    int i,j;
    for (i = 0, j = 0; str[i]; i++) {
        if (!isspace(str[i])) {
            str[j++] = str[i];
        }
    }
    str[j] = '\0';
}

/*
按照delim拆分字符串input
1.注意需要预先分配一个buf
2.函数返回的指针会指向buf
3.使用free()函数释放返回的指针
*/
char ** str_split(char *input,char *delim,int buf_size){
    char **result=NULL;
    char *saveptr;
    char *token;
    char buf[buf_size];
    strcpy(buf,input);
    if ((token=__strtok_r(buf,delim,&saveptr))!=NULL)
    {
        int i=0;
        result=realloc(result,(i+1)*sizeof(char *));
        trim(token);
        result[i]=calloc(strlen(token)+1,1);
        strcpy(result[i],token);
        strcpy(input,token);
        strcat(input,delim);
        while ((token=__strtok_r(NULL,delim,&saveptr))!=NULL)
        {   ++i;
            result=realloc(result,(i+1)*sizeof(char *));
            trim(token);
            result[i]=calloc(strlen(token)+1,1);
            strcpy(result[i],token);
            strcat(input,token);
            strcat(input,delim);
        }
        result=realloc(result,(i+2)*sizeof(char *));
        result[i+1]=NULL;
        input[strlen(input)-strlen(delim)]='\0';
    }
    return result;
}

int str_len(char **str){
    if (str==NULL)
        return -1;
    int i=0;
    while (str[i])
    {
        i++;
    }
    return i;
}

void str_free(char **str){
    if (str==NULL)
        return;
    int i=0;
    while (str[i]!=NULL)
    {
        free(str[i]);
        i++;
    }
    free(str);
}

//规整字符串中空格
void str_neat(char *input){
    if (input==NULL)
        return;
    int len=strlen(input)+1;
    char **ret=str_split(input," ",len);
    str_free(ret);
}

void split_dilm(char *light,char *right,const char *str,const char dilm){
    if (str==NULL)
        return;
    char *last_slash=strrchr(str,dilm);
    if (last_slash==NULL&&right!=NULL)
    {
        strcpy(right,str);
        return;
    }
    if (light!=NULL)
    {
        strncpy(light,str,last_slash-str);
        light[last_slash-str]='\0';
    }
    if (right!=NULL)
    {
        strcpy(right,++last_slash);
    }
    return;
}

//拆分文件和路径
void split_dir_file(char *dir,char *file,const char *filepath){
    split_dilm(dir,file,filepath,'/');
}

//判断某个字符串是否拥有指定后缀成功返回1否则返回0
int string_has_suffix(const char *str, const char *suffix) {
    int n, m, i = 0;
    // char ch = '\0';
    if (str == NULL || suffix == NULL)
    {
        return 0;
    }
    n = strlen(str);
    m = strlen(suffix);
    if (n < m) {
        return 0;
    }
    for (i = m-1; i >= 0;  i--) {
        if (suffix[i] != str[n - m + i]) {
            return 0;
        }
    }
    return 1;
}



/*
1. 注册一个处理函数ini_handler：void ini_handler(void* user,const char* section,const char* key,char* value,long file_lastmtime)
2. user是自定义的结构体,section和key是去空字符不可变字符串指针,value是未去空字符的可变字符串指针
3. succes for 0, error for -1
*/ 
int ini_parse(void* user,const char *path,ini_handler handler,long *mtime){
    //记录文件最后修改时间
    struct stat filestat;
    stat(path,&filestat);
    if (mtime!=NULL)
    {
        *mtime=filestat.st_mtime;
    }
    //解析文件
    FILE *file = fopen(path, "r");
    if (file == NULL) {
       printf("Error: %s opening file\n",path);
       return -1;
    }

    char dir[4096];
    char filename[4096];
    split_dir_file(dir,filename,path);
    char line[4096];
    char section[4096] = "";
    char key_str[4096];
    char value_str[4096];
    while (fgets(line, sizeof(line), file)) {
        line[strlen(line)]='\0';
        if (strchr(line,'[')&&strchr(line,']')) {
            trim(line);
            strncpy(section, line + 1, strlen(line) - 2);
            section[strlen(line) - 2] = '\0';
        } else if (strchr(line, '=')) {
            char *saveptr;
            char *key = __strtok_r(line, "=",&saveptr);
            char *value = __strtok_r(NULL, "\0",&saveptr);
            trim(key);
            strcpy(key_str,key);
            strcpy(value_str,value);
            // printf("ini_parse(): section=%s key=%s value=%s\n",section,key,value);
            handler(user,section,key_str,value_str);
        }
    }
    fclose(file);
    return 0;
}

/*查询目标路径下所有文件*/
char ** load_dir(const char *path,const char *suffix){
    char** files=NULL;
    DIR *dir=opendir(path);
    if (dir != NULL)
    {
        struct dirent *entry;
        int i=0;
        while ((entry=readdir(dir)) != NULL)
        {   
            if (entry->d_type == 8)
            {
                if ( string_has_suffix((char*)entry->d_name,suffix) == 1)
                {
                    files=realloc(files,(i+2)*sizeof(char*));
                    files[i]=malloc((strlen(entry->d_name)+1)*sizeof(char));
                    strcpy(files[i],entry->d_name);
                    i++;
                }
            } 
        }
        if (i>0)
        {
            files[i]=NULL;
        }
        closedir(dir); 

    }else{
        printf("open %s dir error:%s\n",path,strerror(errno));
        return NULL;
    }
    return files;
}
